<script lang="ts">
    import dayjs from "dayjs";
    import type { DatepickerStore } from ".";
    import { clearHms } from "./utils";
    import Icon from "../Common/Icons/Icon.svelte";
    import Day from "./Day.svelte";
    import MonthPane from "./MonthPane.svelte";
    import { _ } from "svelte-i18n";

    const weeks = $derived($_("Datepicker.weeks").split(","));

    const changeCurrentMonth = (store: DatepickerStore, type: "Month" | "FullYear", name: string, op: number, stick: boolean) => {
        const month = store.currentMonth[name === "end" ? 1 : 0];
        month[`set${type}`](month[`get${type}`]() + 1 * op);
        const newMonth = [...store.currentMonth];
        if (stick) {
            const other = newMonth[name === "end" ? 0 : 1];
            other[`set${type}`](other[`get${type}`]() + 1 * op);
        } else {
            if (dayjs(newMonth[0]).format("YYYY-MM") === dayjs(newMonth[1]).format("YYYY-MM") || newMonth[0].getTime() > newMonth[1].getTime()) {
                const other = newMonth[name === "end" ? 0 : 1];
                other[`set${type}`](other[`get${type}`]() + 1 * op);
            }
        }
        store.currentMonth = newMonth;
    };

    const props = $props();
    const store = props.store;
    const type = props.type ?? "date";
    let view = $state("date");
    const onNextMonth = () => {
        changeCurrentMonth(store, "Month", props.name, 1, props.stick);
    };

    const onPrevMonth = () => {
        changeCurrentMonth(store, "Month", props.name, -1, props.stick);
    };

    const onPrevYear = () => {
        changeCurrentMonth(store, "FullYear", props.name, -1, props.stick);
    };

    const onNextYear = () => {
        changeCurrentMonth(store, "FullYear", props.name, 1, props.stick);
    };

    const onShowMonthView = () => {
        view = "month";
    };

    const onBack = () => {
        view = "date";
    };

    const onMonthChange = (date: Date, type: "year" | "month", name: string) => {
        const month: Date = store.currentMonth[name === "end" ? 1 : 0];
        month.setFullYear(date.getFullYear());
        month.setMonth(date.getMonth());
        const newMonth = [...store.currentMonth];
        const method = type === "year" ? "FullYear" : "Month";
        if (props.stick) {
            const other = new Date(month);
            other.setMonth(other.getMonth() + 1 * (name === "end" ? -1 : 1));
            newMonth[name === "end" ? 0 : 1] = other;
        } else {
            if (dayjs(newMonth[0]).format("YYYY-MM") === dayjs(newMonth[1]).format("YYYY-MM") || newMonth[0].getTime() > newMonth[1].getTime()) {
                const other = newMonth[name === "end" ? 0 : 1];
                other[`set${method}`](other[`get${method}`]() + 1 * (name === "end" ? -1 : 1));
            }
        }
        store.currentMonth = newMonth;
    };

    const days = () => {
        const rets = [];
        const first = clearHms(new Date(store.currentMonth[props.name === "end" ? 1 : 0]));

        first.setDate(1);
        const last = new Date(first);
        last.setMonth(last.getMonth() + 1);
        last.setDate(0);

        // 当月第一天是星期几，前面空几个格子
        const index = (first.getDay() + 7 - (dayjs.locale() === "zh-cn" ? 1 : 0)) % 7;
        const start = new Date(first);
        start.setDate(start.getDate() - index - 1);
        for (let i = 0; i < index; i++) {
            rets.push(new Date(start.setDate(start.getDate() + 1)));
        }

        first.setDate(0);
        for (let i = 0; i < last.getDate(); i++) {
            rets.push(new Date(first.setDate(first.getDate() + 1)));
        }

        let end: any = rets[rets.length - 1];
        end = new Date(end);
        for (let i = 0, j: number = 42 - rets.length; i < j; i++) {
            rets.push(new Date(end.setDate(end.getDate() + 1)));
        }

        return rets;
    };

    const dayRows = $derived.by(() => {
        weeks;
        const arr = days();
        const rets = [];
        for (let i = 0; i < arr.length; i += 7) {
            rets.push(arr.slice(i, i + 7));
        }
        return rets;
    });

    const text = () => {
        return dayjs(store.currentMonth[props.name === "end" ? 1 : 0]).format($_("Datepicker.dayPanelFormat"));
    };

    const weekActive = (weekStartDate: any) => {
        if (props.type === "week") {
            return props.value && dayjs(weekStartDate).format("gggg-ww") === dayjs(props.value).format("gggg-ww");
        }
        if (props.type === "weekRange") {
            return (
                (store.range?.[0] && dayjs(weekStartDate).format("gggg-ww") === dayjs(store.range?.[0]).format("gggg-ww")) ||
                (store.range?.[1] && dayjs(weekStartDate).format("gggg-ww") === dayjs(store.range?.[1]).format("gggg-ww"))
            );
        }
    };
</script>

<div class="cm-date-picker-date">
    {#if view === "date"}
        <div class="cm-date-picker-date-inner">
            <div class="cm-date-picker-date-header">
                <div class="cm-date-picker-header-arrow">
                    <Icon icon="chevronsLeft" onclick={onPrevYear} />
                </div>
                <div class="cm-date-picker-header-arrow">
                    <Icon icon="chevronLeft" onclick={onPrevMonth} />
                </div>
                <span class="cm-date-picker-date-info" onclick={onShowMonthView}>{text()}</span>
                <div class="cm-date-picker-header-arrow">
                    <Icon icon="chevronRight" onclick={onNextMonth} />
                </div>
                <div class="cm-date-picker-header-arrow">
                    <Icon icon="chevronsRight" onclick={onNextYear} />
                </div>
            </div>
            <div class="cm-date-picker-date-body">
                <div class="cm-date-picker-week-line">
                    {#each weeks as item}
                        <div>{item}</div>
                    {/each}
                </div>
                <div class="cm-date-picker-date-days">
                    {#each dayRows as row (row)}
                        {@const weekHover = dayjs(row[row.length - 1]).format("gggg-ww") === dayjs(store.hoverDate).format("gggg-ww")}
                        <div class={{ "cm-date-picker-date-row": true, "cm-date-picker-date-row-hover": weekHover, "cm-date-picker-date-row-active": weekActive(row[row.length - 1]) }}>
                            {#each row as day (day)}
                                <Day
                                    range={props.type === "weekRange" ? [] : store.range}
                                    hoverDate={store.hoverDate}
                                    type={props.type}
                                    {day}
                                    value={props.value}
                                    name={props.name}
                                    month={store.currentMonth[props.name === "end" ? 1 : 0]}
                                />
                            {/each}
                        </div>
                    {/each}
                </div>
            </div>
            <div class="cm-date-picker-date-footer"></div>
        </div>
    {/if}
    {#if view === "month"}
        <MonthPane {...props} {onBack} {onMonthChange} />
    {/if}
</div>
